﻿
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.ComponentModel;
//using System.Text.Encoding.CodePages;

namespace MuXue.Zyiz.Template.Common
{
    public static class Extensions
    {
        #region 提供标准 MD5 加密的方法
        /// <summary>
        /// 提供标准 MD5 加密的方法
        /// </summary>
        /// <param name="cort"></param>
        /// <returns></returns>
        public static string Ext_GetStandMD5(this string cort)
        {
            System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

            byte[] bytes = System.Text.Encoding.GetEncoding("gbk").GetBytes(cort);
            bytes = md5.ComputeHash(bytes);
            md5.Clear();
            string ret = string.Empty;
            for (int i = 0; i < bytes.Length; i++)
            {
                ret += Convert.ToString(bytes[i], 16).PadLeft(2, '0');
            }
            return ret.PadLeft(32, '0');
        }
        #endregion

        #region 提供 Base64 MD5 加密的方法
        /// <summary>
        /// 提供 Base64 MD5 加密的方法，Base64 MD5 加密为不可逆算法
        /// </summary>
        /// <param name="cort"> 需要加密的字符串（string） </param>
        /// <returns> 加密后的字符串（string） </returns>
        public static string Ext_GetEncryptInMD5(this string cort)
        {
            string recort = cort;
            byte[] data = System.Text.Encoding.UTF8.GetBytes(cort.ToCharArray());   // 获得要加密的字段，并且转化为 byte[] 
            MD5 md5 = new MD5CryptoServiceProvider();   // 实例一个加密的对象
            byte[] Result = md5.ComputeHash(data);
            recort = Convert.ToBase64String(Result);    // 将加密后的数组转化为字段 

            return recort;
        }
        #endregion

        #region 加密字符串
        /// <summary>
        /// 加密字符串
        /// </summary>
        /// <returns></returns>
        public static string Ext_GetEncrypt(this string pToEncrypt)
        {
            byte[] desKey = new byte[] { 0x16, 0x09, 0x14, 0x15, 0x07, 0x01, 0x05, 0x08 };
            byte[] desIV = new byte[] { 0x16, 0x09, 0x14, 0x15, 0x07, 0x01, 0x05, 0x08 };

            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            try
            {
                //把字符串放到byte数组中
                //原来使用的UTF8编码，我改成Unicode编码了，不行
                byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
                //byte[] inputByteArray=Encoding.Unicode.GetBytes(pToEncrypt);

                //建立加密对象的密钥和偏移量
                //原文使用ASCIIEncoding.ASCII方法的GetBytes方法
                //使得输入密码必须输入英文文本
                des.Key = desKey;       // ASCIIEncoding.ASCII.GetBytes(sKey);
                des.IV = desIV;         //ASCIIEncoding.ASCII.GetBytes(sKey);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(),
                    CryptoStreamMode.Write);
                //Write the byte array into the crypto stream
                //(It will end up in the memory stream)
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();

                //Get the data back from the memory stream, and into a string
                StringBuilder ret = new StringBuilder();
                foreach (byte b in ms.ToArray())
                {
                    //Format as hex
                    ret.AppendFormat("{0:X2}", b);
                }
                ret.ToString();
                return ret.ToString();
            }
            catch
            {
                return pToEncrypt;
            }
            finally
            {
                des = null;
            }
        }
        #endregion

        #region 解密字符串
        /// <summary>
        /// 解密字符串
        /// </summary>
        /// <param name="pToDecrypt"></param>
        /// <returns></returns>
        public static string Ext_GetDecrypt(this string pToDecrypt)
        {
            byte[] desKey = new byte[] { 0x16, 0x09, 0x14, 0x15, 0x07, 0x01, 0x05, 0x08 };
            byte[] desIV = new byte[] { 0x16, 0x09, 0x14, 0x15, 0x07, 0x01, 0x05, 0x08 };

            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            try
            {
                //Put the input string into the byte array
                byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
                for (int x = 0; x < pToDecrypt.Length / 2; x++)
                {
                    int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
                    inputByteArray[x] = (byte)i;
                }

                //建立加密对象的密钥和偏移量，此值重要，不能修改
                des.Key = desKey;           //ASCIIEncoding.ASCII.GetBytes(sKey);
                des.IV = desIV;             //ASCIIEncoding.ASCII.GetBytes(sKey);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
                //Flush the data through the crypto stream into the memory stream
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();

                //Get the decrypted data back from the memory stream
                //建立StringBuild对象，CreateDecrypt使用的是流对象，必须把解密后的文本变成流对象
                StringBuilder ret = new StringBuilder();

                return System.Text.Encoding.Default.GetString(ms.ToArray());
            }
            catch
            {
                return pToDecrypt;
            }
            finally
            {
                des = null;
            }
        }
        #endregion

        public static String GetEnumDescription(this Enum obj)
        {
            if (obj == default(Enum))
                return string.Empty;

            Type type = obj.GetType();
            var fieldInfo = type.GetField(Enum.GetName(type, obj));
            if (fieldInfo != null)
            {
                if (Attribute.IsDefined(fieldInfo, typeof(DescriptionAttribute)))
                {
                    var description =
                        Attribute.GetCustomAttribute(fieldInfo, typeof(DescriptionAttribute)) as DescriptionAttribute;

                    if (description != null)
                        return description.Description;
                }
            }
            return string.Empty;
        }
    }
}